<?php

namespace App\Service\Message\v1_1_0;

use App\Constants\ErrorCode;
use App\Helpers\AliyunUtil;
use App\Helpers\ConfigUtil;
use App\Model\CoinLog;
use App\Model\Gift;
use App\Model\GiftLog;
use App\Model\Message;
use App\Model\Service\ConsumeService;
use App\Model\User;
use App\Model\UserBlacklist;
use App\Model\UserCoin;
use App\Model\UserPackBag;
use App\Model\UserProfile;
use App\Service\BaseService;
use Psr\EventDispatcher\EventDispatcherInterface;
use App\Event\ConsumeEvent;
use App\Helpers\RedisUtil;

/**
 * 送礼
 */
class GiftSendService extends BaseService
{
    public function handle()
    {
	$userId = $this->getUserId();
        $giftId = $this->request->input('gift_id', 0);
        $chatUserId = $this->request->input('chat_user_id', 0);
        $giftNum = intval($this->request->input('gift_num', 1));
        $sendFrom = intval($this->request->input('send_from', GiftLog::FROM_SEND));
        if (!$chatUserId || !$giftId || $userId == $chatUserId || $giftNum <= 0) {
            log_user_result($userId, "ChatUid:{$chatUserId}==GiftId:{$giftId}==ParamError");
            return $this->setError(ErrorCode::PARAMETER_ERROR, '参数错误～');
        }

        //加入同步锁
        if (RedisUtil::concurrentLock($key = "GiftSend_{$userId}", 3)) {
            log_user_result($userId, "gift_send==Key:{$key}");
            return $this->setError(ErrorCode::OP_TOO_MANY, '送礼太频繁，请勿重复提交！');
        }

        //拉黑关系
        if (UserBlacklist::check($userId, $chatUserId)) {
            log_user_result($userId, "ChatUid:{$chatUserId}==GiftId:{$giftId}==AddBlack");
            return $this->setError(ErrorCode::CHAT_BLACK_LMT, '你已经将对方拉黑，暂无法送礼～');
        }

        //礼物数据
        $giftItem = Gift::getInfo($giftId);
        $giftCoin = $giftItem['coin'] * $giftNum;
	//背包礼物
        if (Gift::checkPackBagGift($giftItem)) {
            $result = $this->sendPackBag(
                $userId,
                $chatUserId,
                $giftItem,
                $giftNum,
                $giftCoin,
                $sendFrom);
	
            if ($result['ret'] != 0) return $result;
        } else {
            $myCoin = UserCoin::getUserInfo($userId);
            //金币消耗
            $senderCost = $sendFrom == GiftLog::FROM_VIDEO_CALL_FREE ? false : true;
            //金币收入（女生特殊礼物-对方无收入）
            $hostSendSpecial = in_array($giftId, explode(',', env('HOST_SHOW_GIFTID', '62')));
            $receiverGain = $hostSendSpecial ? false : true;
            //非背包礼物
            if ($senderCost && $myCoin['total_coin'] < $giftCoin) {
                log_user_result($userId, "ChatUid:{$chatUserId}==GiftId:{$giftId}==CoinNotEnough");
                return $this->setError(ErrorCode::COIN_NOT_ENOUGH, '剩余金币不够送礼, 可以先充值哦~');
            }
            //当天赠送金币已达限制
            $totalCost = GiftLog::checkTotalCost($userId, date('Y-m-d'));
            if ($senderCost && ($totalCost + $giftCoin) >= env('GIFT_SEND_COIN_LIMIT', 20000)) {
                return $this->setError(ErrorCode::GIFT_COST_LIMIT, '当日送礼额度已达上限，请理性消费哦～');
	    }
            //记录入库
            $record = GiftLog::addRecord($userId, $chatUserId, $giftId, $giftCoin, false, $sendFrom, 0, $giftNum);
            if ($record) {
                $result = ConsumeService::sendGift($record, [], $receiverGain, $senderCost);
	    }
            log_user_result($userId, "ChatUid:{$chatUserId}==GiftId:{$giftId}");
        }

        //回调
        $this->sendGiftCallback($userId, $chatUserId, $giftItem, $giftNum);
        return [
            'result' => 1,
            'gift_tip' => $hostSendSpecial ? '' : '',
        ];
    }

    /**
     * 赠送背包礼物
     */
    function sendPackBag(
        $userId = 0,
        $chatUserId = 0,
        $giftItem = [],
        $giftNum = 1,
        $giftCoin = 1,
        $sendFrom = 0
    ) {
        $giftId = $giftItem['id'];
        $result = UserPackBag::usePackBag($userId, $giftId, $giftNum);
        if (!$result) {
            log_user_result($userId, "NoEnough==GiftId:{$giftId}");
            return $this->setError(ErrorCode::PACK_BAG_USE_ERROR, '无足够礼物可使用！');
        }
        //记录入库
        $record = GiftLog::addRecord($userId, $chatUserId, $giftId, $giftCoin, false, $sendFrom, 0, $giftNum);
        $incomeCoin = round($giftCoin * (1 - ConfigUtil::getConsumeRate($userId)), 1);
        //对方收入到账
        ConsumeService::gainIncome(
            $chatUserId,
            $incomeCoin,
            CoinLog::FROM_GET_GIFT,
            $userId
        );
        //消费事件
        make(EventDispatcherInterface::class)->dispatch(new ConsumeEvent(
            $userId,
            $chatUserId,
            $giftCoin,
            $incomeCoin,
            false,
            CoinLog::FROM_INVITE_INCOME_GIFT
        ));
        log_user_result($userId, "ChatUid:{$chatUserId}==GiftId:{$giftId}");
        return ['result' => 1];
    }

    /**
     * 送礼回调
     */
    function sendGiftCallback($userId = 0, $chatUserId = 0, $giftItem = [], $giftNum = 1)
    {
        if ($giftItem['coin'] <= 10) return;
        //透传
        $onlineUserIds = UserProfile::getOnlineUsers(0, 300);
        $onlineUserIds = array_unique(array_merge($onlineUserIds, [$userId, $chatUserId]));
        $profiles = UserProfile::getUsersProfile($onlineUserIds, true);
        Message::sendSlient($onlineUserIds, 'SEND_GIFT_TIP', [
            'sender_name' => $profiles[$userId]['nick_name'],
            'sender_id' => $userId,
            'avatar' => UserProfile::buildAvatar($profiles[$userId]['avatar'], 200),
            'icon' => AliyunUtil::imageResize(AliyunUtil::IMG_HOST_V2 . $giftItem['icon'], 120, 120),
            'gift_name' => $giftItem['name'],
            'gift_id' => $giftItem['id'],
            'gift_num' => $giftNum
        ]);
    }
}
